extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
}
#include <QImage>
int main() {
    const int width = 1920;
    const int height = 1080;
    const int fps = 25;
    
    QImage  m_img;
    m_img.load("/home/dll/1080.png");
    if(m_img.format() != QImage::Format_ARGB32)
    {
        m_img.convertTo(QImage::Format_ARGB32);
    }
    if(m_img.format() == QImage::Format_ARGB32)
    {   
        printf("convert to ARGB32\n");
    }

    // 查找H.264编码器
    AVCodec *codec = (AVCodec *)avcodec_find_encoder(AV_CODEC_ID_H264);
    if (!codec) {
        fprintf(stderr, "Codec not found\n");
        return -1;
    }

    // 分配编码器上下文
    AVCodecContext *codecCtx = avcodec_alloc_context3(codec);
    if (!codecCtx) {
        fprintf(stderr, "Could not allocate video codec context\n");
        return -1;
    }

    // 设置编码参数
    codecCtx->bit_rate = 400000;                 // 比特率
    codecCtx->width = width;                     // 宽度
    codecCtx->height = height;                   // 高度
    codecCtx->time_base = (AVRational){1, fps};  // 帧率
    codecCtx->framerate = (AVRational){fps, 1};  // 帧率
    codecCtx->gop_size = 10;                     // 每10帧插入一个I帧
    codecCtx->max_b_frames = 1;                  // 使用B帧
    codecCtx->pix_fmt = AV_PIX_FMT_YUV420P;      // 输出格式是YUV420P

    // 打开编码器
    if (avcodec_open2(codecCtx, codec, NULL) < 0) {
        fprintf(stderr, "Could not open codec\n");
        return -1;
    }

    // 创建输出文件
    FILE *file = fopen("output.h264", "wb");
    if (!file) {
        fprintf(stderr, "Could not open output file\n");
        return -1;
    }

    // 创建帧并设置参数
    AVFrame *frame = av_frame_alloc();
    if (!frame) {
        fprintf(stderr, "Could not allocate video frame\n");
        return -1;
    }
    frame->format = codecCtx->pix_fmt;
    frame->width = codecCtx->width;
    frame->height = codecCtx->height;
    
    if (av_frame_get_buffer(frame, 32) < 0) {
        fprintf(stderr, "Could not allocate frame buffer\n");
        return -1;
    }

    // 创建SwsContext来转换像素格式（从RGBA到YUV420P）
    SwsContext *swsCtx = sws_getContext(width, height, AV_PIX_FMT_BGRA,
                                        width, height, AV_PIX_FMT_YUV420P,
                                        SWS_BILINEAR, NULL, NULL, NULL);


    // 创建数据包
    AVPacket pkt;
    av_init_packet(&pkt);
    pkt.data = NULL;
    pkt.size = 0;

    // 编码帧并输出到文件
    for (int i = 0; i < 1000; i++) {  // 假设我们编码100帧图像
        // 将RGBA转换为YUV420P
        uint8_t *srcSlice[] = { m_img.bits(), nullptr };
        int srcStride[] = { width * 4 };
        sws_scale(swsCtx, srcSlice, srcStride, 0, height, frame->data, frame->linesize);

        // 设置PTS（显示时间戳）
        frame->pts = i;

        // 发送帧给编码器
        if (avcodec_send_frame(codecCtx, frame) < 0) {
            fprintf(stderr, "Error sending frame for encoding\n");
            return -1;
        }

        // 接收编码后的数据包
        while (avcodec_receive_packet(codecCtx, &pkt) == 0) {
            // 将编码后的H.264数据写入文件
            fwrite(pkt.data, 1, pkt.size, file);
            av_packet_unref(&pkt);
        }
    }

    // 刷新编码器（将剩余的数据编码并输出）
    avcodec_send_frame(codecCtx, NULL);
    while (avcodec_receive_packet(codecCtx, &pkt) == 0) {
        fwrite(pkt.data, 1, pkt.size, file);
        av_packet_unref(&pkt);
    }

    // 释放资源
    fclose(file);
    av_frame_free(&frame);
    avcodec_free_context(&codecCtx);
    sws_freeContext(swsCtx);

    return 0;
}
